package service

import (
	"encoding/json"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"gochat/common"
	"gochat/domain/request"
	"gochat/domain/response/result"
	"gochat/models"
	"gochat/utils/rabbitmq"
	"gorm.io/gorm"
	"log"
	"strconv"
	"time"
)

type FriendServiceImpl struct {
}

func (f FriendServiceImpl) FriendRequest(c *gin.Context, sendId uint, ReceiveId uint, message string) {
	db := common.DB
	friendRequest := models.FriendRequest{
		SenderId:   sendId,
		ReceiverId: ReceiveId,
		Message:    message,
	}
	//判断是否为好友
	affected := db.Model(&models.UserFriends{}).Where("user_id = ? AND friend_id = ?", sendId, ReceiveId).First(&models.UserFriends{}).RowsAffected
	if affected != 0 {
		result.Fail(c, 400, "对方已经是你的好友")
		return
	}

	rw := db.Model(&models.FriendRequest{}).Where("sender_id = ? AND receiver_id = ?", sendId, ReceiveId).First(&models.FriendRequest{}).RowsAffected
	if rw != 0 {
		result.Fail(c, 400, "已发送过好友申请")
		return
	}
	//err := db.Transaction(func(tx *gorm.DB) error {
	//	err := tx.Model(&models.FriendRequest{}).Save(&friendRequest).Error
	//	return err
	//})
	err := db.Model(&models.FriendRequest{}).Save(&friendRequest).Error
	if err != nil {
		result.Fail(c, 500, "发送好友请求失败")
		return
	}
	producer := rabbitmq.NewProducer(common.RabbitPools)
	var messagePayload = request.FriendRequestMessagePayload{
		Id:        friendRequest.ID,
		FromUser:  sendId,
		Message:   message,
		Timestamp: time.Now().Unix(),
		ToUser:    ReceiveId,
	}
	body, err := json.Marshal(messagePayload)
	if err != nil {
		log.Println(err)
		result.Fail(c, 500, "发送好友请求失败")
		return
	}
	err = producer.Push("friend.request", rabbitmq.DirectExchange, "friend.request.userId."+strconv.Itoa(int(ReceiveId)), string(body))
	if err != nil {
		log.Println(err)
		result.Fail(c, 500, "发送好友请求失败")
		return
	}
	result.Ok(c, "发送好友请求成功")
}
func (u FriendServiceImpl) AddFriends(userId uint, friendId uint) error {
	db := common.DB
	// 检查是否已经是好友
	var count int64
	db.Model(&models.UserFriends{}).
		Where("user_id = ? AND friend_id = ?", userId, friendId).
		Count(&count)
	if count > 0 {
		return errors.New("已经是好友了")
	}
	err := db.Transaction(func(tx *gorm.DB) error {
		// 插入记录 A -> B
		if err := tx.Create(&models.UserFriends{
			UserId:   userId,
			FriendId: friendId,
			Status:   1,
		}).Error; err != nil {
			return err
		}
		// 插入记录 B -> A
		if err := tx.Create(&models.UserFriends{
			UserId:   friendId,
			FriendId: userId,
			Status:   1,
		}).Error; err != nil {
			return err
		}
		return nil
	})
	if err != nil {
		return errors.New("添加好友失败")
	}
	return nil
}

func (f FriendServiceImpl) ReceiveFriendRequest(conn *websocket.Conn, uid string) {
	defer conn.Close()
	consumer := rabbitmq.NewConsumer(common.RabbitPools)
	err := consumer.Subscribe("friend.request", rabbitmq.DirectExchange, []string{"friend.request.userId." + uid},
		"friend.request."+uid, func(msg string) {
			log.Println("接收到消息")
			var rst request.FriendRequestMessagePayload
			if err := json.Unmarshal([]byte(msg), &rst); err != nil {
				log.Println("解析错误:", err)
				return
			}
			if err := conn.WriteMessage(websocket.TextMessage, []byte(msg)); err != nil {
				log.Println("写入 WebSocket 错误:", err)
				return
			}
		})
	if err != nil {
		log.Println("RabbitMQ 订阅失败:", err)
	}
}

func (f FriendServiceImpl) AcceptFriendRequest(c *gin.Context, friendReqId string, status string) {
	err := common.DB.Transaction(func(tx *gorm.DB) error {
		var friendRequest models.FriendRequest
		t := tx.Model(&friendRequest).
			Where("id=?", friendReqId).
			Select("status").
			Update("status", status)
		if t.Error != nil {
			log.Println(t.Error)
			return errors.New("服务器异常")
		}
		if status == "1" {
			firstRst := tx.First(&friendRequest, friendReqId)
			if firstRst.Error != nil {
				log.Println("查询错误")
				return errors.New("服务器异常")
			}
			//TODO
			err := f.AddFriends(friendRequest.SenderId, friendRequest.ReceiverId)
			if err != nil {
				return err
			}
		}
		return nil
	})
	if err != nil {
		result.Fail(c, 500, err.Error())
		return
	}
	result.Ok(c, "发送成功")
}

func (f FriendServiceImpl) FriendListByUid(c *gin.Context, uid int64) {
	db := common.DB
	var user models.UserBasic
	subQuery := db.Table("friends").
		Select("friend_id").
		Where("user_id = ? AND status = ?", uid, 1)
	err := db.Preload("Friends", "id IN (?)", subQuery).
		First(&user, uid).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			result.Fail(c, 400, "用户不存在")
			return
		}
	}
	var rst []request.FriendListRequest
	for _, friend := range user.Friends {
		var temp models.UserFriends
		err := db.Model(&temp).First(&temp, "user_id=? and friend_id=?", uid, friend.ID).Error
		if err != nil {
			log.Println(err)
			result.Fail(c, 500, "服务器异常")
			return
		}
		rst = append(rst, request.FriendListRequest{
			Id:       friend.ID,
			Nickname: friend.NickName,
			Username: friend.UserName,
			Header:   friend.Header,
			Status:   uint(temp.Status),
			Remark:   temp.Remark,
		})
	}
	result.Ok(c, rst)
}
